﻿using System;
using System.IO;
using System.Linq;
using Common;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.Filters;

namespace Extensions.Services
{
    public static class AddSwagger
    {
        public static IServiceCollection AddSwaggerSetup(this IServiceCollection services)
        {
            if (services == null)
            { 
                throw new ArgumentNullException(nameof(services));
            }

            var config = Appsettings.app<SwaggerConfig>("Swagger");
            ArgumentNullException.ThrowIfNull(config);
            if (!config.Enable)
            {
                return services;
            }
            var apiName = config.ApiName??"";
            var xmlCommentsUrl = config.XmlCommentsUrl??"";
            services.AddSwaggerGen(options =>
            {
                typeof(ApiVersion).GetEnumNames().ToList().ForEach(version =>
                {
                    options.SwaggerDoc(version, new OpenApiInfo()
                    {
                        Version = version,
                        Title = $"{apiName} API",
                        Description = "框架说明文档",
                        //TermsOfService = new Uri(""),
                        Contact = new OpenApiContact()// 这边可以写一些url 跳转
                        {
                            Name = $"{apiName} API"
                        }
                    });
                });
                try
                {
                    var basePath = AppContext.BaseDirectory;
                    var apiPath = Path.Combine(basePath, xmlCommentsUrl, "API.xml");
                    var modelPath = Path.Combine(basePath, xmlCommentsUrl, "Domain.xml");
                    options.IncludeXmlComments(apiPath, true);// controller注释
                    options.IncludeXmlComments(modelPath);
                }
                catch
                {
                    Console.WriteLine("swagger对象的描述xml加载错误，请检查项目的配置输出和配置的XmlCommentsUrl参数是否正确");
                }
               
                // 开启小锁
                options.OperationFilter<AddResponseHeadersFilter>();
                options.OperationFilter<AppendAuthorizeToSummaryOperationFilter>();
                // 在header添加tokne
                options.OperationFilter<SecurityRequirementsOperationFilter>();
                options.AddSecurityDefinition(SecuritySchemeType.OAuth2.ToString(), new OpenApiSecurityScheme()
                {
                    Description = "Jwt授权 请在下方的输入框中输入Bearer {token} （注意中间要有一个空格）",
                    Name = "Authorization",
                    In = ParameterLocation.Header,// jwt方在header中
                    Type = SecuritySchemeType.ApiKey
                });
            });

            return services;
        }

        public static IApplicationBuilder UseSwaggerSetup(this IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (app == null) throw new ArgumentNullException(nameof(app));
            if (env == null) throw new ArgumentNullException(nameof(env));
            var config = Appsettings.app<SwaggerConfig>("Swagger");
            ArgumentNullException.ThrowIfNull(config);
            if (env.IsDevelopment()&&config.Enable)//如果是开发 环境  才使用swagger中间件
            {
                var apiName = config.ApiName??"";
                app.UseSwagger();
                app.UseSwaggerUI(options =>
                {
                    typeof(ApiVersion).GetEnumNames().ToList().ForEach(version =>
                    {
                        options.SwaggerEndpoint($"/swagger/{version}/swagger.json", $"{apiName} {version}");//访问swaggerjson的地址
                        options.RoutePrefix = string.Empty;//表示根目录就是swagger index页面的位置
                        options.HeadContent =
                            @"<script async=""async"" id=""mini-profiler"" src=""/profiler/includes.min.js?v=4.2.22+4563a9e1ab"" 
                                data-version=""4.2.22+4563a9e1ab"" data-path=""/profiler/"" 
                                data-current-id=""f7bcd793-a09d-46c8-bcf0-f0d94b5f1e84"" 
                                data-ids=""f7bcd793-a09d-46c8-bcf0-f0d94b5f1e84"" data-position=""Left"""" 
                                data-scheme=""Light"" 
                                data-authorized=""true"" 
                                data-max-traces=""15"" 
                                data-toggle-shortcut=""Alt+P"" 
                                data-trivial-milliseconds=""2.0"" 
                                data-ignored-duplicate-execute-types=""Open,OpenAsync,Close,CloseAsync"">
                            </script>";
                    });

                    //路径配置，设置为空，表示直接访问该文件，  直接首页访问swagger
                    //路径配置，设置为空，表示直接在根域名（localhost:8001）访问该文件,注意localhost:8001/swagger是访问不到的，
                    //这个时候去launchSettings.json中把"launchUrl": "swagger/index.html"去掉， 然后直接访问localhost:8001/index.html即可
                    //这里添加miniprofile的 前端需要的script
                    //options.HeadContent = "";
                });

            }
            return app;
        }
        public static IApplicationBuilder UseSwaggerSetup(this IApplicationBuilder app)
        {
            if (app == null) throw new ArgumentNullException(nameof(app));
            var config = Appsettings.app<SwaggerConfig>("Swagger");
            ArgumentNullException.ThrowIfNull(config);
            if (config.Enable)//如果是开发 环境  才使用swagger中间件
            {
                var apiName = config.ApiName??"";
                app.UseSwagger();
                app.UseSwaggerUI(options =>
                {
                    typeof(ApiVersion).GetEnumNames().ToList().ForEach(version =>
                    {
                        options.SwaggerEndpoint($"/swagger/{version}/swagger.json", $"{apiName} {version}");//访问swaggerjson的地址
                        options.RoutePrefix = string.Empty;//表示根目录就是swagger index页面的位置
                        options.HeadContent =
                            @"<script async=""async"" id=""mini-profiler"" src=""/profiler/includes.min.js?v=4.2.22+4563a9e1ab"" 
                                data-version=""4.2.22+4563a9e1ab"" data-path=""/profiler/"" 
                                data-current-id=""f7bcd793-a09d-46c8-bcf0-f0d94b5f1e84"" 
                                data-ids=""f7bcd793-a09d-46c8-bcf0-f0d94b5f1e84"" data-position=""Left"""" 
                                data-scheme=""Light"" 
                                data-authorized=""true"" 
                                data-max-traces=""15"" 
                                data-toggle-shortcut=""Alt+P"" 
                                data-trivial-milliseconds=""2.0"" 
                                data-ignored-duplicate-execute-types=""Open,OpenAsync,Close,CloseAsync"">
                            </script>";
                    });

                    //路径配置，设置为空，表示直接访问该文件，  直接首页访问swagger
                    //路径配置，设置为空，表示直接在根域名（localhost:8001）访问该文件,注意localhost:8001/swagger是访问不到的，
                    //这个时候去launchSettings.json中把"launchUrl": "swagger/index.html"去掉， 然后直接访问localhost:8001/index.html即可
                    //这里添加miniprofile的 前端需要的script
                    //options.HeadContent = "";
                });

            }
            return app;
        }
    }
    public enum ApiVersion
    {
        v1 = 1,
        v2 = 2
    }
    /// <summary>
    /// swagger配置对象
    /// </summary>
    public class SwaggerConfig
    {
        /// <summary>
        /// api的名字
        /// </summary>
        public string? ApiName { get; set; }
        /// <summary>
        /// 读取xml注释文件的中间路径
        /// </summary>
        public string? XmlCommentsUrl { get; set; }
        /// <summary>
        /// 是否启用
        /// </summary>
        public bool Enable { get; set; }
    }
}
